"""
系统功能测试脚本
测试慢性病风险预测系统的各个模块
"""

import sys
import os
import pandas as pd
import numpy as np
from datetime import datetime

# 添加项目路径
sys.path.append('.')

def test_data_preprocessing():
    """测试数据预处理模块"""
    print("测试数据预处理模块...")
    
    try:
        from data.preprocessing import DataPreprocessor
        
        preprocessor = DataPreprocessor()
        
        # 测试用户输入预处理
        user_data = {
            'age': 45,
            'gender': 'male',
            'height': 175,
            'weight': 75,
            'systolic_bp': 130,
            'diastolic_bp': 85,
            'blood_glucose': 105,
            'smoking': True,
            'family_history': False,
            'exercise_frequency': 'regularly'
        }
        
        processed_data = preprocessor.preprocess_user_input(user_data)
        print(f"✓ 用户数据预处理成功: {len(processed_data)} 个特征")
        
        # 测试批量数据预处理
        sample_data = preprocessor.generate_sample_data(100)
        processed_batch = preprocessor.preprocess_batch_data(sample_data)
        print(f"✓ 批量数据预处理成功: {processed_batch.shape}")
        
        return True
        
    except Exception as e:
        print(f"✗ 数据预处理测试失败: {e}")
        return False

def test_xgboost_model():
    """测试XGBoost模型"""
    print("\n测试XGBoost模型...")
    
    try:
        from models.xgboost_model import XGBoostPredictor
        from data.preprocessing import DataPreprocessor
        
        # 创建模型和预处理器
        xgb_model = XGBoostPredictor()
        preprocessor = DataPreprocessor()
        
        # 生成测试数据
        sample_data = preprocessor.generate_sample_data(500)
        
        # 准备训练数据
        feature_columns = [
            'age', 'gender', 'bmi', 'systolic_bp', 'diastolic_bp',
            'blood_glucose', 'cholesterol', 'heart_rate', 'smoking',
            'drinking', 'family_history', 'exercise_frequency', 'diet_preference'
        ]
        
        X = sample_data[feature_columns]
        y_ht = sample_data['hypertension_risk']
        y_dm = sample_data['diabetes_risk']
        
        # 训练模型
        xgb_model.train(X, y_ht, y_dm)
        print("✓ XGBoost模型训练成功")
        
        # 测试预测
        test_input = X.iloc[0].to_dict()
        prediction = xgb_model.predict(test_input)
        print(f"✓ XGBoost预测成功: 综合风险 {prediction['overall_risk']['probability']:.3f}")
        
        return True
        
    except Exception as e:
        print(f"✗ XGBoost模型测试失败: {e}")
        return False

def test_lstm_model():
    """测试LSTM模型"""
    print("\n测试LSTM模型...")
    
    try:
        from models.lstm_model import LSTMModelWrapper
        
        # 创建模型
        lstm_model = LSTMModelWrapper()
        
        # 生成测试时序数据
        timeseries_data = lstm_model.generate_sample_timeseries(60)
        print(f"✓ 生成时序数据: {len(timeseries_data)} 条记录")
        
        # 测试预测（不训练，使用模拟预测）
        test_data = timeseries_data.head(1).to_dict('records')[0]
        prediction = lstm_model.predict(test_data)
        print(f"✓ LSTM预测成功: 预测血压 {prediction['predicted_values']['systolic_bp']:.1f}")
        
        return True
        
    except Exception as e:
        print(f"✗ LSTM模型测试失败: {e}")
        return False

def test_model_fusion():
    """测试模型融合"""
    print("\n测试模型融合...")
    
    try:
        from models.xgboost_model import XGBoostPredictor
        from models.lstm_model import LSTMModelWrapper
        from models.model_fusion import ModelFusion
        
        # 创建模型
        xgb_model = XGBoostPredictor()
        lstm_model = LSTMModelWrapper()
        fusion_model = ModelFusion(xgb_model, lstm_model)
        
        # 测试融合预测
        test_data = {
            'age': 50,
            'gender': 'male',
            'height': 170,
            'weight': 70,
            'systolic_bp': 125,
            'diastolic_bp': 80,
            'blood_glucose': 100,
            'smoking': False,
            'family_history': True,
            'exercise_frequency': 'regularly'
        }
        
        prediction = fusion_model.predict(test_data)
        print(f"✓ 模型融合预测成功: 综合风险 {prediction['overall_risk']['probability']:.3f}")
        
        return True
        
    except Exception as e:
        print(f"✗ 模型融合测试失败: {e}")
        return False

def test_shap_explainer():
    """测试SHAP解释器"""
    print("\n测试SHAP解释器...")
    
    try:
        from utils.shap_explainer import SHAPExplainer
        
        # 创建解释器
        explainer = SHAPExplainer()
        
        # 测试解释
        input_data = {
            'age': 45,
            'bmi': 26.5,
            'systolic_bp': 135,
            'blood_glucose': 110,
            'smoking': 1,
            'family_history': 0
        }
        
        prediction_result = {
            'overall_risk': {'probability': 0.65, 'risk_level': 'high'},
            'hypertension_risk': {'probability': 0.7, 'risk_level': 'high'},
            'diabetes_risk': {'probability': 0.6, 'risk_level': 'high'}
        }
        
        explanation = explainer.explain_prediction(input_data, prediction_result)
        print(f"✓ SHAP解释成功: {len(explanation['top_risk_factors'])} 个主要风险因素")
        
        return True
        
    except Exception as e:
        print(f"✗ SHAP解释器测试失败: {e}")
        return False

def test_intervention_recommender():
    """测试干预推荐器"""
    print("\n测试干预推荐器...")
    
    try:
        from utils.intervention_recommender import InterventionRecommender
        
        # 创建推荐器
        recommender = InterventionRecommender()
        
        # 测试推荐
        prediction_result = {
            'overall_risk': {'probability': 0.65, 'risk_level': 'high'},
            'hypertension_risk': {'probability': 0.7, 'risk_level': 'high'},
            'diabetes_risk': {'probability': 0.6, 'risk_level': 'high'}
        }
        
        user_data = {
            'age': 45,
            'bmi': 26.5,
            'smoking': True
        }
        
        recommendations = recommender.get_recommendations(prediction_result, user_data)
        print(f"✓ 干预推荐成功: {len(recommendations['lifestyle_interventions'])} 类建议")
        
        return True
        
    except Exception as e:
        print(f"✗ 干预推荐器测试失败: {e}")
        return False

def test_demo_data_generator():
    """测试演示数据生成器"""
    print("\n测试演示数据生成器...")
    
    try:
        from demo_data_generator import DemoDataGenerator
        
        # 创建生成器
        generator = DemoDataGenerator()
        
        # 生成小量测试数据
        patient_data = generator.generate_patient_data(100)
        timeseries_data = generator.generate_timeseries_data(patient_data['patient_id'].head(10).tolist(), 30)
        
        print(f"✓ 生成患者数据: {len(patient_data)} 条")
        print(f"✓ 生成时序数据: {len(timeseries_data)} 条")
        
        return True
        
    except Exception as e:
        print(f"✗ 演示数据生成器测试失败: {e}")
        return False

def run_all_tests():
    """运行所有测试"""
    print("慢性病风险预测系统 - 功能测试")
    print("=" * 50)
    print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print()
    
    tests = [
        ("数据预处理", test_data_preprocessing),
        ("XGBoost模型", test_xgboost_model),
        ("LSTM模型", test_lstm_model),
        ("模型融合", test_model_fusion),
        ("SHAP解释器", test_shap_explainer),
        ("干预推荐器", test_intervention_recommender),
        ("演示数据生成器", test_demo_data_generator)
    ]
    
    results = []
    
    for test_name, test_func in tests:
        try:
            result = test_func()
            results.append((test_name, result))
        except Exception as e:
            print(f"✗ {test_name}测试异常: {e}")
            results.append((test_name, False))
    
    # 输出测试结果
    print("\n" + "=" * 50)
    print("测试结果汇总:")
    print("-" * 30)
    
    passed = 0
    for test_name, result in results:
        status = "✓ 通过" if result else "✗ 失败"
        print(f"{test_name}: {status}")
        if result:
            passed += 1
    
    print(f"\n总计: {passed}/{len(results)} 个测试通过")
    
    if passed == len(results):
        print("\n🎉 所有测试通过！系统功能正常。")
        print("可以运行 'python start_system.py' 启动系统。")
    else:
        print(f"\n⚠️  有 {len(results) - passed} 个测试失败，请检查相关模块。")
    
    return passed == len(results)

def main():
    """主函数"""
    success = run_all_tests()
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()



